package com.jiajia.study.netty.chapter01;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class NettyServer {
    public static void main(String[] args) {
        // 1. 线程组-主要监是监听客户端的连接请求
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        // 2. 线程组-主要是监听客户端的读写请求
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        // 3. 启动类
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        // 4. 指定线程组
        serverBootstrap.group(bossGroup,workerGroup);

        // 5. 指定 NIO 模式
        serverBootstrap.channel(NioServerSocketChannel.class);

        // 6. 双向链表管理
        serverBootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
            @Override
            protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                // 责任链，指定自定义处理业务的 Handler
                nioSocketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                    @Override
                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//                        super.channelRead(ctx, msg);
                        ByteBuf buf = (ByteBuf) msg;

                        byte[] bytes = new byte[buf.readableBytes()];
                        // 将数据读到 byte 数组中
                        buf.readBytes(bytes);
                        // 将 byte 数组转成 string
                        String data = new String(bytes, StandardCharsets.UTF_8);
                        System.out.println("客户端请求数据是: "+ data);
                        // 给客户端发送消息
                        String res = "hello world >>> client";
                        ByteBuf resBuf = getByteBuf(ctx,res);
                        // 见 byteBuf 写到channel 并刷新
                        ctx.writeAndFlush(resBuf);
                    }

                    private ByteBuf getByteBuf(ChannelHandlerContext ctx, String res) {
                        ByteBuf buffer = ctx.alloc().buffer();
                        byte[] bytes = res.getBytes(Charset.forName("utf-8"));
                        buffer.writeBytes(bytes);
                        return buffer;
                    }
                });
            }
        });

        serverBootstrap.bind(9999);

    }
}
